#include <iostream>
#include <tuple>
#include <type_traits>
#include <typeinfo>

template <typename T, typename Tuple>
struct TupleContains;

template <typename T, typename... Us>
struct TupleContains<T, std::tuple<Us...>>
    : std::disjunction<std::is_same<T, Us>...> {};

template <typename Tuple1, typename Tuple2>
struct TupleCat;

template <typename... Types1, typename... Types2>
struct TupleCat<std::tuple<Types1...>, std::tuple<Types2...>> {
    using type = std::tuple<Types1..., Types2...>;
};

template <typename TypeList, template <typename, typename> class Comparator>
struct Sort;

template <template <typename, typename> class Comparator>
struct Sort<std::tuple<>, Comparator> {
    using type = std::tuple<>;
};

template <typename Head,
          typename... Tail,
          template <typename, typename> class Comparator>
struct Sort<std::tuple<Head, Tail...>, Comparator> {
    using SortedTail = typename Sort<std::tuple<Tail...>, Comparator>::type;
    using type = std::conditional_t<
        TupleContains<Head, SortedTail>::value,
        SortedTail,
        typename TupleCat<std::tuple<Head>, SortedTail>::type>;
};

template <typename T1, typename T2>
struct SizeComparator
    : std::integral_constant<bool, (sizeof(T1) < sizeof(T2))> {};

int main() {
    using TypeList = std::tuple<double, char, float, int>;
    using SortedTypeList = typename Sort<TypeList, SizeComparator>::type;

    std::cout << "Original type list: " << typeid(TypeList).name() << std::endl;
    std::cout << "Sorted type list: " << typeid(SortedTypeList).name()
              << std::endl;

    return 0;
}

// #include <iostream>
// #include <tuple>
// #include <type_traits>

// // 类型排序的基本模板
// template <typename TypeList, template <typename, typename> class Comparator>
// struct Sort;

// // 类型排序的递归模板
// template <typename Head, typename... Tail, template <typename, typename>
// class Comparator> struct Sort<std::tuple<Head, Tail...>, Comparator> {
//     // 使用内部模板找到最小元素
//     using min_element = std::conditional_t<
//         Comparator<Head, typename Sort<std::tuple<Tail...>,
//         Comparator>::min_element>::value, Head, typename
//         Sort<std::tuple<Tail...>, Comparator>::min_element>;

//     // 删除最小元素
//     using remaining = typename std::tuple_cat<
//         std::conditional_t<std::is_same_v<Head, min_element>, std::tuple<>,
//         std::tuple<Head>>, typename Sort<std::tuple<Tail...>,
//         Comparator>::remaining>;

//     // 将最小元素添加到排序后的类型列表中
//     using type = decltype(std::tuple_cat(std::tuple<min_element>(),
//     remaining()));
// };

// // 类型排序的模板特化，用于处理空类型列表的情况
// template <template <typename, typename> class Comparator>
// struct Sort<std::tuple<>, Comparator> {
//     using min_element = void;
//     using remaining   = std::tuple<>;
//     using type        = std::tuple<>;
// };

// // 按照类型的字节数进行排序的比较函数
// template <typename T1, typename T2>
// struct SizeComparator : std::integral_constant<bool, (sizeof(T1) <
// sizeof(T2))> {};

// int main() {
//     // 将类型列表 std::tuple<double, char, float, int>
//     按照类型的字节数进行排序 using TypeList       = std::tuple<double, char,
//     float, int>; using SortedTypeList = Sort<TypeList, SizeComparator>::type;

//     // 输出原始类型列表和排序后的类型列表，以验证排序是否正确
//     std::cout << "Original type list: " << typeid(TypeList).name() <<
//     std::endl; std::cout << "Sorted type list: " <<
//     typeid(SortedTypeList).name() << std::endl;

//     return 0;
// }